home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / cross / devpic.lha / devpic / source / picprog.c next >
C/C++ Source or Header  |  2000-04-03  |  16KB  |  669 lines

  1. #include <exec/memory.h>
  2. #include <clib/dos_protos.h>
  3. #include <clib/exec_protos.h>
  4. #include <clib/misc_protos.h>
  5. #include <clib/timer_protos.h>
  6. #include <pragmas/exec_sysbase_pragmas.h>
  7. #include <pragmas/timer_pragmas.h>
  8. #include <pragmas/misc_pragmas.h>
  9. #include <pragmas/dos_pragmas.h>
  10. #include <resources/misc.h>
  11. #include <dos/dos.h>
  12.  
  13. struct Library *DOSBase, *SysBase, *TimerBase, *MiscBase;
  14. struct MsgPort *timereplyport;
  15. struct timerequest *timereq;
  16. __far struct FileInfoBlock fib;
  17. struct {
  18.     STRPTR from;
  19.     ULONG* force;
  20.     ULONG* smartflash;
  21.     ULONG* configword;
  22.     ULONG verify;
  23. } arg = { 0, 0, 0, 0, 0 };
  24. #define TEMPLATE "FROM/A,FORCE/N,SF=SMARTFLASH/N,CW=CONFIGWORD/N,V=VERIFY/S"
  25. STRPTR inpoint;
  26. static ULONG pvout, psout;
  27. ULONG rc;
  28. __far static UWORD deltabuf[8192];
  29. UBYTE unhex(void);
  30. UBYTE unhexbyte(void);
  31.  
  32. ULONG picReadCode(void);
  33. ULONG picRecv(ULONG);
  34. ULONG picSetup(void);
  35. void picCmd(ULONG);
  36. void picSend(ULONG, ULONG);
  37. void picWait(ULONG);
  38. void picInc(void);
  39. void picIncNum(ULONG);
  40. void picEnterProgMode(void);
  41. void picUndocmd(void);
  42. void picEraseProg(ULONG);
  43. void picProgOnly(ULONG);
  44. void picCleanup(void);
  45. void picLoadCode(ULONG);
  46. void picLoadConf(ULONG);
  47.  
  48. enum {
  49. LOADCONF = 0,
  50. UNDOC1,
  51. LOADCODE,
  52. LOADDATA,
  53. READCODE,
  54. READDATA,
  55. INCADDR,
  56. UNDOC2,
  57. BEGINPROG,
  58. ERASECODE,
  59. ERASEDATA = 11,
  60. PROGONLY = 24
  61. };
  62.  
  63. __saveds main()
  64. {
  65.     SysBase = *((struct Library **)4L);
  66.     rc = 20;
  67.     if(DOSBase = OpenLibrary("dos.library",36))
  68.     {
  69.         if(timereplyport = CreateMsgPort()) // ReplyPort for time requests
  70.         {
  71.             if(timereq = (struct timerequest *)CreateIORequest(timereplyport,sizeof(struct timerequest)))
  72.             {
  73.                 if(!OpenDevice(TIMERNAME,UNIT_MICROHZ,(struct IORequest *)timereq,0))
  74.                 {
  75.                     struct RDArgs *rda;
  76.                     Printf("%s  © Russian Digital Computing\n",6+"$VER: picprog 1.4 "__AMIGADATE__);
  77.                     if(rda = ReadArgs(TEMPLATE,(LONG *)&arg,NULL))
  78.                     {
  79.                         BPTR infile;
  80.                         if(infile = Open(arg.from,MODE_OLDFILE))
  81.                         {
  82.                             STRPTR indata;
  83.                             ExamineFH(infile,&fib);
  84.                             if(inpoint = indata = AllocVec(fib.fib_Size+1000,MEMF_CLEAR))
  85.                             {
  86.                                 *(indata+fib.fib_Size+998) = 0x0A;
  87.                                 if(-1!=Read(infile,indata,fib.fib_Size))
  88.                                 {
  89.                                     ULONG end = 0, erc = 0, nl = 0;
  90.                                     ULONG line = 0, actualen = 0, lastaddr = 0;
  91.                                     while(TRUE)
  92.                                     {
  93.                                         line++;
  94.                                         if(':'==*inpoint)
  95.                                         {
  96.                                             STRPTR checkpoint = ++inpoint;
  97.                                             UBYTE len = unhex();
  98.                                             UBYTE hiaddr = unhex();
  99.                                             UBYTE loaddr = unhex();
  100.                                             UBYTE type = unhex();
  101.                                             UBYTE sum = len + loaddr + hiaddr + type;
  102.                                             ULONG checklen = (len+5)<<1;
  103.                                             while(checklen--)
  104.                                             {
  105.                                                 UBYTE tb = *checkpoint++;
  106.                                                 if((tb<'0')||
  107.                                                     (tb>'f')||
  108.                                                     ((tb>'9')&&(tb<'A'))||
  109.                                                     ((tb>'F')&&(tb<'a')))
  110.                                                 {
  111.                                                     erc = 3;
  112.                                                     goto hexend;
  113.                                                 }
  114.                                             }
  115.                                             switch(type)
  116.                                             {
  117.                                                 case 0: //data
  118.                                                 {
  119.                                                     ULONG fulladdr = (hiaddr<<8) + loaddr;
  120.                                                     if(lastaddr!=fulladdr)
  121.                                                     {
  122.                                                         nl=1;
  123.                                                     }
  124.                                                     lastaddr = fulladdr+len;
  125.                                                     if(lastaddr>actualen)
  126.                                                     {
  127.                                                         actualen=lastaddr;
  128.                                                     }
  129.                                                     while(len--) sum += unhex();
  130.                                                     if((UBYTE)(sum+unhex()))
  131.                                                     {
  132.                                                         erc = 1;
  133.                                                         goto hexend;
  134.                                                     }
  135.                                                     break;
  136.                                                 }
  137.                                                 case 1: //EOF
  138.                                                 {
  139.                                                     if(loaddr|hiaddr|len) //it is not a typo
  140.                                                     {
  141.                                                         erc = 3;
  142.                                                         goto hexend;
  143.                                                     }
  144.                                                     if((UBYTE)(sum+unhex()))
  145.                                                     {
  146.                                                         erc = 1;
  147.                                                     }
  148.                                                     end = 1;
  149.                                                     goto hexend;
  150.                                                 }
  151.                                                 case 2: //segment address
  152.                                                 case 3: //segment start address
  153.                                                 case 4: //linear address
  154.                                                 case 5: //linear start address
  155.                                                 {
  156.                                                     erc = 3;
  157.                                                     goto hexend;
  158.                                                 }
  159.                                                 default:
  160.                                                 {
  161.                                                     erc = 2;
  162.                                                     goto hexend;
  163.                                                 }
  164.                                             }
  165.                                         }
  166.                                         while((0x0A!=*inpoint)&&(0x0D!=*inpoint))
  167.                                         {
  168.                                             inpoint++;
  169.                                         }
  170.                                         if((0x0D==*inpoint)&&(0x0A==inpoint[1]))
  171.                                         {
  172.                                             inpoint++;
  173.                                         }
  174.                                         if((inpoint++)>(indata+fib.fib_Size))
  175.                                         {
  176.                                             break;
  177.                                         }
  178.                                     }
  179.                                     hexend:
  180.                                     if(erc)
  181.                                     {
  182.                                         static STRPTR errtxt[] = {
  183.                                             "Checksum error at",
  184.                                             "Unknown record type at",
  185.                                             "Invalid",
  186.                                             "Unsupported record type (useless for PIC16 object files) at" };
  187.                                         Printf("%s line %ld\n",errtxt[erc-1],line);
  188.                                         if(!actualen)
  189.                                         {
  190.                                             Printf("Possibly n%s","ot an !ntel Hex file\n");
  191.                                         }
  192.                                     }
  193.                                     else
  194.                                     {
  195.                                         if(actualen)
  196.                                         {
  197.                                             if(end)
  198.                                             {
  199.                                                 STRPTR outdata = inpoint = indata;
  200.                                                 ULONG outmem = 0;
  201.                                                 if(nl)
  202.                                                 {
  203.                                                     //Printf("Warning: non-linear file\n");
  204.                                                     if(outdata = AllocVec(actualen,MEMF_ANY))
  205.                                                     {
  206.                                                         ULONG count = actualen;
  207.                                                         STRPTR fillpoint = outdata;
  208.                                                         while(count--)
  209.                                                         {
  210.                                                             *fillpoint++ = 0xff;
  211.                                                         }
  212.                                                         outmem = 1;
  213.                                                     }
  214.                                                     else
  215.                                                     {
  216.                                                         Printf("Can't allocate memory for output file\n");
  217.                                                     }
  218.                                                 }
  219.                                                 if(outdata)
  220.                                                 {
  221.                                                     UWORD *wordbuf = (UWORD*)outdata;
  222.                                                     ULONG wc = actualen>>1, wordcount, word;
  223.                                                     ULONG wordswritten = 0;
  224.                                                     if(wc>8192)
  225.                                                     {
  226.                                                         wc=8192;
  227.                                                     }
  228.                                                     while(':'==*inpoint++)
  229.                                                     {
  230.                                                         UBYTE len = unhex();
  231.                                                         UBYTE hiaddr = unhex();
  232.                                                         UBYTE loaddr = unhex();
  233.                                                         UBYTE type = unhex();
  234.                                                         if(!type)
  235.                                                         {
  236.                                                             STRPTR outpoint = outdata + (hiaddr<<8) + loaddr;
  237.                                                             while(len--) *outpoint++ = unhex();
  238.                                                         }
  239.                                                         inpoint += 2;
  240.                                                         while('!'>*inpoint) inpoint++;
  241.                                                     }
  242.  
  243.                                                     // PIC16Fxxx PROGRAMMING START
  244.  
  245.                                                     if(picSetup())
  246.                                                     {
  247.                                                         picEnterProgMode();
  248.                                                         if(arg.force)
  249.                                                         {
  250.                                                             picLoadConf(*arg.force); //0x3ffa äëÿ 16f84, 0x3f3a äëÿ 16f876
  251.                                                             picIncNum(7);
  252.                                                             picUndocmd();
  253.                                                             picEraseProg(10);
  254.                                                             picUndocmd();
  255.                                                             picEnterProgMode();
  256.                                                         }
  257.                                                         word = 0;
  258.                                                         wordcount = wc;
  259.                                                         if(arg.smartflash)
  260.                                                         {
  261.                                                             ULONG words = 0, wordiff = 0;
  262.                                                             if(arg.force)
  263.                                                             {
  264.                                                                 words++;
  265.                                                                 wordiff++;
  266.                                                             }
  267.                                                             else
  268.                                                             {
  269.                                                                 while(wordcount--)
  270.                                                                 {
  271.                                                                     UWORD val = (*wordbuf>>8)|(*wordbuf<<8);
  272.                                                                     if(!(0xC000 & val))
  273.                                                                     {
  274.                                                                         if(val != (deltabuf[word] = picReadCode()))
  275.                                                                         {
  276.                                                                             wordiff++;
  277.                                                                         }
  278.                                                                         words++;
  279.                                                                     }
  280.                                                                     picInc();
  281.                                                                     wordbuf++;
  282.                                                                     word++;
  283.                                                                 }
  284.                                                             }
  285.                                                             if(wordiff)
  286.                                                             {
  287.                                                                 picEnterProgMode();
  288.                                                                 word = 0;
  289.                                                                 wordcount = wc;
  290.                                                                 wordbuf = (UWORD*)outdata;
  291.                                                                 if((wordiff<<1)>words)
  292.                                                                 {
  293.                                                                     picLoadCode(0xffff);
  294.                                                                     picCmd(ERASECODE);
  295.                                                                     picEraseProg(10);
  296.                                                                     picEnterProgMode();
  297.                                                                     while(wordcount--)
  298.                                                                     {
  299.                                                                         UWORD val = (*wordbuf>>8)|(*wordbuf<<8);
  300.                                                                         if(!(0xC000 & val))
  301.                                                                         {
  302.                                                                             ULONG tempdat;
  303.                                                                             picLoadCode(val);
  304.                                                                             picProgOnly(*arg.smartflash);
  305.                                                                             tempdat = picReadCode();
  306.                                                                             if(val != tempdat)
  307.                                                                             {
  308.                                                                                 Printf("Error writing location %ld\n",word);
  309.                                                                                 Printf("must be %lx but read %lx\n",val,tempdat);
  310.                                                                                 goto picerr;
  311.                                                                             }
  312.                                                                             wordswritten++;
  313.                                                                         }
  314.                                                                         picInc();
  315.                                                                         wordbuf++;
  316.                                                                         word++;
  317.                                                                     }
  318.                                                                 }
  319.                                                                 else
  320.                                                                 {
  321.                                                                     while(wordcount--)
  322.                                                                     {
  323.                                                                         UWORD val = (*wordbuf>>8)|(*wordbuf<<8);
  324.                                                                         if(!(0xC000 & val))
  325.                                                                         {
  326.                                                                             if(val != deltabuf[word])
  327.                                                                             {
  328.                                                                                 ULONG tempdat;
  329.                                                                                 picLoadCode(val);
  330.                                                                                 picEraseProg((*arg.smartflash)<<1);
  331.                                                                                 tempdat = picReadCode();
  332.                                                                                 if(val != tempdat)
  333.                                                                                 {
  334.                                                                                     Printf("Error writing location %ld\n",word);
  335.                                                                                     Printf("must be %lx but read %lx\n",val,tempdat);
  336.                                                                                     goto picerr;
  337.                                                                                 }
  338.                                                                                 wordswritten++;
  339.                                                                             }
  340.                                                                         }
  341.                                                                         picInc();
  342.                                                                         wordbuf++;
  343.                                                                         word++;
  344.                                                                     }
  345.                                                                 }
  346.                                                             }
  347.                                                         }
  348.                                                         else
  349.                                                         {
  350.                                                             while(wordcount--)
  351.                                                             {
  352.                                                                 UWORD val = (*wordbuf>>8)|(*wordbuf<<8);
  353.                                                                 ULONG tempdat;
  354.                                                                 if(!(0xC000 & val))
  355.                                                                 {
  356.                                                                     tempdat = picReadCode();
  357.                                                                     if(val != tempdat)
  358.                                                                     {
  359.                                                                         picLoadCode(val);
  360.                                                                         picEraseProg(10);
  361.                                                                         tempdat = picReadCode();
  362.                                                                         if(val != tempdat)
  363.                                                                         {
  364.                                                                             Printf("Error writing location %ld\n",word);
  365.                                                                             Printf("must be %lx but read %lx\n",val,tempdat);
  366.                                                                             goto picerr;
  367.                                                                         }
  368.                                                                         wordswritten++;
  369.                                                                     }
  370.                                                                 }
  371.                                                                 picInc();
  372.                                                                 wordbuf++;
  373.                                                                 word++;
  374.                                                             }
  375.                                                         }
  376.                                                         if(arg.verify)
  377.                                                         {
  378.                                                             wordbuf = (UWORD*)outdata;
  379.                                                             picEnterProgMode();
  380.                                                             word = 0;
  381.                                                             wordcount = wc;
  382.                                                             while(wordcount--)
  383.                                                             {
  384.                                                                 UWORD val = (*wordbuf>>8)|(*wordbuf<<8);
  385.                                                                 ULONG tempdat;
  386.                                                                 if(!(0xC000 & val))
  387.                                                                 {
  388.                                                                     if(val != (tempdat=picReadCode()))
  389.                                                                     {
  390.                                                                         Printf("Verify error at location %ld\n",word);
  391.                                                                         Printf("must be %lx but read %lx\n",val,tempdat);
  392.                                                                         goto picerr;
  393.                                                                     }
  394.                                                                 }
  395.                                                                 picInc();
  396.                                                                 wordbuf++;
  397.                                                                 word++;
  398.                                                             }
  399.                                                         }
  400.                                                         if(arg.configword)
  401.                                                         {
  402.                                                             picLoadConf(*arg.configword);
  403.                                                             picIncNum(7);
  404.                                                             if((*arg.configword) != picReadCode())
  405.                                                             {
  406.                                                                 picLoadCode(*arg.configword);
  407.                                                                 picEraseProg(10);
  408.                                                                 if((*arg.configword) != picReadCode())
  409.                                                                 {
  410.                                                                     Printf("Error writing configuration word\n");
  411.                                                                     goto picerr;
  412.                                                                 }
  413.                                                                 wordswritten++;
  414.                                                             }
  415.                                                         }
  416.                                                         rc = 0;
  417.                                                         if(wordswritten)
  418.                                                         {
  419.                                                             Printf("Programming finished, %ld location%s done\n",wordswritten,wordswritten>1?"s":1+"s");
  420.                                                         }
  421.                                                         else
  422.                                                         {
  423.                                                             Printf("No differencies - nothing to do!\n");
  424.                                                         }
  425.                                                         picerr:
  426.                                                         picCleanup();
  427.                                                     }
  428.  
  429.                                                     // PIC16Fxxx PROGRAMMING END
  430.  
  431.                                                     if(outmem)
  432.                                                     {
  433.                                                         FreeVec(outdata);
  434.                                                     }
  435.                                                 }
  436.                                             }
  437.                                             else
  438.                                             {
  439.                                                 Printf("EOF record not found\n");
  440.                                             }
  441.                                         }
  442.                                         else
  443.                                         {
  444.                                             if(end)
  445.                                             {
  446.                                                 Printf("File does not contain any data\n");
  447.                                             }
  448.                                             else
  449.                                             {
  450.                                                 Printf("N%s","ot an !ntel Hex file\n");
  451.                                             }
  452.                                         }
  453.                                     }
  454.                                 }
  455.                                 FreeVec(indata);
  456.                             }
  457.                             else
  458.                             {
  459.                                 Printf("Can't allocate memory for input file\n");
  460.                             }
  461.                             Close(infile);
  462.                         }
  463.                         else
  464.                         {
  465.                             Printf("Can't open source file\n");
  466.                         }
  467.                         FreeArgs(rda);
  468.                     }
  469.                     else
  470.                     {
  471.                         Printf("Error in arguments\n");
  472.                     }
  473.                     CloseDevice((struct IORequest *)timereq);
  474.                 }
  475.                 else
  476.                 {
  477.                     Printf("Can't open %s\n",TIMERNAME);
  478.                 }
  479.                 DeleteIORequest((struct IORequest *)timereq);
  480.             }
  481.             else
  482.             {
  483.                 Printf("Can't create IORequest\n");
  484.             }
  485.             DeleteMsgPort(timereplyport);
  486.         }
  487.         else
  488.         {
  489.             Printf("Can't create msgport\n");
  490.         }
  491.         CloseLibrary(DOSBase);
  492.     }
  493.     return(rc);
  494. }
  495.  
  496. UBYTE unhex(void)
  497. {
  498.     return((UBYTE)((unhexbyte()<<4)+unhexbyte()));
  499. }
  500.  
  501. UBYTE unhexbyte(void)
  502. {
  503.     if(*inpoint<='9')
  504.     {
  505.         return((UBYTE)((*inpoint++)-'0'));
  506.     }
  507.     return((UBYTE)(((*inpoint++)|32)-'a'+10));
  508. }
  509.  
  510.  
  511.  
  512. /**************************/
  513. /*                        */
  514. /*   HARDWARE INTERFACE   */
  515. /*                        */
  516. /**************************/
  517.  
  518. #define PORTVALUE *((STRPTR)0xbfe101)
  519. #define PORTSTATE *((STRPTR)0xbfe301)
  520. #define BSET(val,bit) val|=(1<<bit)
  521. #define BCLR(val,bit) val&=(~(1<<bit))
  522. #define BTST(val,bit) val & (1<<bit)
  523.  
  524. ULONG picSetup(void)
  525. {
  526.     if(MiscBase = OpenResource(MISCNAME))
  527.     {
  528.         STRPTR owner;
  529.         if(owner = AllocMiscResource(MR_PARALLELPORT,"PIC programmer"))
  530.         {
  531.             Printf("Can't allocate parallel port - it is owned by %s\n",owner);
  532.             return(0);
  533.         }
  534.         else return(1);
  535.     }
  536.     else
  537.     {
  538.         Printf("Can't open %s\n",MISCNAME);
  539.         return(0);
  540.     }
  541. }
  542.  
  543. void picCleanup(void)
  544. {
  545.     psout = 4+8+16;
  546.     PORTSTATE = psout;
  547.     pvout = 4;
  548.     PORTVALUE = pvout;
  549.     pvout = 8+16;
  550.     PORTVALUE = pvout;
  551.     FreeMiscResource(MR_PARALLELPORT);
  552. }
  553.  
  554. void picCmd(ULONG cmd)
  555. {
  556.     picSend(cmd,6);
  557. }
  558.  
  559. void picInc(void)
  560. {
  561.     picSend(INCADDR,6);
  562. }
  563.  
  564. void picIncNum(ULONG num)
  565. {
  566.     while(num--)
  567.     {
  568.         picInc();
  569.     }
  570. }
  571.  
  572. void picUndocmd(void)
  573. {
  574.     picCmd(UNDOC1);
  575.     picCmd(UNDOC2);
  576. }
  577.  
  578. void picEraseProg(ULONG time)
  579. {
  580.     picCmd(BEGINPROG);
  581.     picWait(time);
  582. }
  583.  
  584. void picProgOnly(ULONG time)
  585. {
  586.     picCmd(PROGONLY);
  587.     picWait(time);
  588. }
  589.  
  590. void picWait(ULONG time)
  591. {
  592.     timereq->tr_node.io_Command = TR_ADDREQUEST;
  593.     timereq->tr_time.tv_secs = 0;
  594.     timereq->tr_time.tv_micro = time*1000;
  595.     DoIO((struct IORequest *)timereq);
  596. }
  597.  
  598. ULONG picReadCode(void)
  599. {
  600.     picCmd(READCODE);
  601.     return(0x3fff&(picRecv(16)>>1));
  602. }
  603.  
  604. void picLoadCode(ULONG data)
  605. {
  606.     picCmd(LOADCODE);
  607.     picSend(data<<1,16);
  608. }
  609.  
  610. void picLoadConf(ULONG data)
  611. {
  612.     picCmd(LOADCONF);
  613.     picSend(data<<1,16);
  614. }
  615.  
  616. void picSend(ULONG val, ULONG bits)
  617. {
  618.     BSET(psout,0);
  619.     PORTSTATE = psout;
  620.     while(bits--)
  621.     {
  622.         BSET(pvout,1);
  623.         if(BTST(val,0))
  624.         {
  625.             BSET(pvout,0);
  626.         }
  627.         else
  628.         {
  629.             BCLR(pvout,0);
  630.         }
  631.         PORTVALUE = pvout;
  632.         BCLR(pvout,1);
  633.         PORTVALUE = pvout;
  634.         val >>= 1;
  635.     }
  636. }
  637.  
  638. ULONG picRecv(ULONG bits)
  639. {
  640.     ULONG val = 0;
  641.     BCLR(psout,0);
  642.     PORTSTATE = psout;
  643.     while(bits--)
  644.     {
  645.         BSET(pvout,1);
  646.         PORTVALUE = pvout;
  647.         BCLR(pvout,1);
  648.         PORTVALUE = pvout;
  649.         val >>= 1;
  650.         if(BTST(PORTVALUE,0))
  651.         {
  652.             BSET(val,15);
  653.         }
  654.     }
  655.     return(val);
  656. }
  657.  
  658. void picEnterProgMode(void)
  659. {
  660.     psout = 1+2+4+8+16;
  661.     PORTSTATE = psout;
  662.     pvout = 0;
  663.     PORTVALUE = pvout;
  664.     BSET(pvout,2);
  665.     PORTVALUE = pvout;
  666.     BCLR(pvout,2);
  667.     PORTVALUE = pvout;
  668. }
  669.